package com.xxl.job.executor.service.jobhandler;

import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.xxl.job.executor.entity.JobResultDTO;
import com.xxl.job.executor.util.CrontabUtil;
import com.xxl.job.executor.util.IpUtil;
import com.xxl.job.executor.svc.CronJobService;
import com.xxl.job.executor.util.UserUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class CronJobExecutor {

    @Autowired
    private ExecutorCallbackService executorCallbackService; // 服务层，用于与数据库交互

    @XxlJob("InitCronJobTask")
    public void InitCronJobTask() throws Exception {
        String sessionId = XxlJobHelper.getJobParam();
        String user = UserUtil.getCurrentUser();

        // 获取服务器的IP地址
        String ip = IpUtil.getLocalIp();
        try {
            // 获取定时任务并拆解为调度时间和命令
            List<CrontabUtil.CronTask> cronTasks = CrontabUtil.getCrontabTasks();

            JobResultDTO result = createJobResult(ip, true, "任务初始化成功", user, cronTasks);

            // 发送成功回调
            sendCallbackToInit(result, sessionId);
        } catch (Exception e) {
            // 任务失败时，发送失败回调
            JobResultDTO jobResultDTO = createJobResult(ip, false, "任务初始化失败: " + e.getMessage(), user, null);

            // 发送失败回调
            sendCallbackToInit(jobResultDTO, sessionId);
        }
    }

    @XxlJob("DownCronJobTask")
    public void downCronJobTask() throws Exception {
        String params = XxlJobHelper.getJobParam();
        XxlJobHelper.log("DownCronJobTask 被调用，参数: " + params);
        // 获取本地 IP
        String localIp = IpUtil.getLocalIp();
        if (localIp == null) {
            throw new RuntimeException("无法获取本地IP地址");
        }

        // 初始化结果对象
        JobResultDTO result = new JobResultDTO();
        String[] paramParts = params.split(",");
        // 参数校验
        if (paramParts.length < 5) {
            throw new IllegalArgumentException("参数格式不正确: " + params);
        }

        String schedule = paramParts[0];
        String command = paramParts[1];
        String serverIp = paramParts[2];
        String sessionId = paramParts[3];
        String user = paramParts[4];

        String currentUser = UserUtil.getCurrentUser();
        XxlJobHelper.log("当前用户是:" + currentUser + "调度中心发送用户:"+user);
        if (user.equals(currentUser)){
            // 设置通用的结果信息
            result = createJobResult(localIp, false, "", currentUser, null);

            // 执行任务禁用逻辑
            if (serverIp.equals(localIp)) {
                System.out.println("正在禁用任务：调度时间：" + schedule + "，命令：" + command);
                boolean success = CrontabUtil.disableCronTask(schedule, command);
                if (success) {
                    result.setSuccess(true);
                    result.setMessage("禁用成功");
                } else {
                    result.setMessage("未找到匹配的任务，禁用失败");
                }
            } else {
                result.setMessage("服务器IP不匹配，禁用失败");
            }

            // 发送回调
            sendCallbackToScheduler(result, sessionId);
        }else {
            result = createJobResult(localIp, false, "当前用户与执行器运行用户不符", currentUser, null);
            sendCallbackToScheduler(result, sessionId);
        }
    }

    @XxlJob("UpCronJobTask")
    public void upCronJobTask() throws Exception{
        String params = XxlJobHelper.getJobParam();
        XxlJobHelper.log("UpCronJobTask 被调用，参数: " + params);

        // 初始化结果对象
        JobResultDTO result = new JobResultDTO();
        String[] paramParts = params.split(",");
        String currentUser = UserUtil.getCurrentUser();
        XxlJobHelper.log("当前用户是:" + currentUser);

        // 参数校验
        if (paramParts.length < 5) {
            throw new IllegalArgumentException("参数格式不正确: " + params);
        }

        String schedule = paramParts[0];
        String command = paramParts[1];
        String serverIp = paramParts[2];
        String sessionId = paramParts[3];
        String user = paramParts[4];

        // 获取本地 IP
        String localIp = IpUtil.getLocalIp();
        if (localIp == null) {
            throw new RuntimeException("无法获取本地IP地址");
        }

        if (user.equals(currentUser)){
            // 设置通用的结果信息
            result = createJobResult(localIp, false, "", currentUser, null);

            // 执行任务禁用逻辑
            if (serverIp.equals(localIp)) {
                System.out.println("正在启用任务：调度时间：" + schedule + "，命令：" + command);
                boolean success = CrontabUtil.enableCronTask(schedule, command);
                if (success) {
                    result.setSuccess(true);
                    result.setMessage("启用成功");
                } else {
                    result.setMessage("未找到匹配的任务，启用失败");
                }
            } else {
                result.setMessage("服务器IP不匹配，启用失败");
            }

            // 发送回调
            sendCallbackToScheduler(result, sessionId);
        }else {
            result = createJobResult(localIp, false, "当前用户与执行器运行用户不符", currentUser, null);
            sendCallbackToScheduler(result, sessionId);
        }
    }

    @XxlJob("UpdateCronJobTask")
    public void updateCronJobTask() throws Exception{
        String params = XxlJobHelper.getJobParam();
        System.out.println("UpdateCronJobTask 被调用，参数: " + params);
        JobResultDTO result = new JobResultDTO();
        // 分割传递的参数
        String[] paramParts = params.split(",");
        if (paramParts.length < 6) {
            throw new IllegalArgumentException("参数格式不正确: " + params);
        }

        String schedule = paramParts[0];
        String newSchedule = paramParts[1];
        String command = paramParts[2];
        String newCommand = paramParts[3];
        String serverIp = paramParts[4];
        String sessionId = paramParts[5];
        String user = paramParts[6];
        String currentUser = UserUtil.getCurrentUser();
        XxlJobHelper.log("当前用户是:" + currentUser + "调度中心发送用户:"+user);

        // 获取本地 IP
        String localIp = IpUtil.getLocalIp();
        if (localIp == null) {
            throw new RuntimeException("无法获取本地IP地址");
        }

        if (user.equals(currentUser)){
            // 设置通用的结果信息
            result = createJobResult(localIp, false, "", currentUser, null);

            // 执行任务修改逻辑
            if (serverIp.equals(localIp)) {
                System.out.println("正在修改任务：调度时间：" + schedule + "，命令：" + command);
                boolean success = CrontabUtil.UpdateCronTask(schedule, newSchedule, command, newCommand);
                if (success) {
                    result.setSuccess(true);
                    result.setMessage("修改成功");
                } else {
                    result.setMessage("未找到匹配的任务，修改失败");
                }
            } else {
                result.setMessage("服务器IP不匹配，修改失败");
            }

            // 发送回调
            sendCallbackToScheduler(result, sessionId);
        }else {
            result = createJobResult(localIp, false, "当前用户与执行器运行用户不符", currentUser, null);
            sendCallbackToScheduler(result, sessionId);
        }
    }

    @XxlJob("AddCronJobTask")
    public void addCronJobTask() throws Exception{
        String params = XxlJobHelper.getJobParam();
        System.out.println("AddCronJobTask 被调用，参数: " + params);
        JobResultDTO result = new JobResultDTO();

        // 分割传递的参数
        String[] paramParts = params.split(",");
        if (paramParts.length < 3) {
            throw new IllegalArgumentException("参数格式不正确: " + params);
        }

        String schedule = paramParts[0];
        String command = paramParts[1];
        String serverIp = paramParts[2];
        String sessionId = paramParts[3];
        String user = paramParts[4];
        String currentUser = UserUtil.getCurrentUser();
        XxlJobHelper.log("当前用户是:" + currentUser + "调度中心发送用户:"+user);

        // 获取本地 IP
        String localIp = IpUtil.getLocalIp();
        if (localIp == null) {
            throw new RuntimeException("无法获取本地IP地址");
        }
        if (user.equals(currentUser)){
            // 设置通用的结果信息
            result = createJobResult(localIp, false, "", currentUser, null);

            // 执行任务修改逻辑
            if (serverIp.equals(localIp)) {
                System.out.println("正在新增任务：调度时间：" + schedule + "，命令：" + command);
                boolean success = CrontabUtil.addCronTask(schedule, command);
                if (success) {
                    result.setSuccess(true);
                    result.setMessage("新增成功");
                } else {
                    result.setMessage("新增失败,请检查执行器逻辑");
                }
            } else {
                result.setMessage("服务器IP不匹配，新增失败");
            }

            // 发送回调
            sendCallbackToScheduler(result, sessionId);
        }else {
            result = createJobResult(localIp, false, "当前用户与执行器运行用户不符", currentUser, null);
            sendCallbackToScheduler(result, sessionId);
        }
    }

    private void sendCallbackToScheduler(JobResultDTO result, String sessionId) {
        ResponseEntity<Map<String, Object>> response = executorCallbackService.sendResultToScheduler(result, sessionId);

        // 处理调度中心的响应
        if (response.getStatusCode() == HttpStatus.OK) {
            System.out.println("回调成功: " + response.getBody());
        } else {
            System.out.println("回调失败: " + response.getBody());
        }
    }

    private void sendCallbackToInit(JobResultDTO result, String sessionId) {
        System.out.println("发送初始化回到函数：" + result.getCronTasks());
        ResponseEntity<Map<String, Object>> response = executorCallbackService.initCrontab(result, sessionId);

        // 处理调度中心的响应
        if (response.getStatusCode() == HttpStatus.OK) {
            System.out.println("回调成功: " + response.getBody());
        } else {
            System.out.println("回调失败: " + response.getBody());
        }
    }

    private JobResultDTO createJobResult(String ip, boolean success, String message, String user, List<CrontabUtil.CronTask> cronTasks) {
        JobResultDTO result = new JobResultDTO();
        result.setServerIp(ip);
        result.setSuccess(success);
        result.setMessage(message);
        result.setUser(user);
        if (cronTasks != null) {
            List<JobResultDTO.CronTaskResult> cronTaskResults = new ArrayList<>();
            for (CrontabUtil.CronTask task : cronTasks) {
                JobResultDTO.CronTaskResult taskResult = new JobResultDTO.CronTaskResult();
                taskResult.setSchedule(task.getSchedule());
                taskResult.setCommand(task.getCommand());
                cronTaskResults.add(taskResult);
            }
            result.setCronTasks(cronTaskResults);
        }
        return result;
    }
}
